package com.ah.shanxi_demo.common;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 精确计算工具类(加，减，乘，除，返回较大值，返回较小值)
 */
public class CalculationUtil {

    /**
     * 提供精确加法计算的add方法
     */
    public static String add(String value1, String value2) {
        return add(value1, value2, 0, 0);
    }

    /**
     * 提供精确加法计算的add方法(默認四捨五入)
     *
     * @param value1 被加数
     * @param value2 加数
     * @param scale  精确范围(小数点后几位)
     */
    public static String add(String value1, String value2, int scale) {
        return add(value1, value2, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 提供精确加法计算的add方法
     *
     * @param value1       被加数
     * @param value2       加数
     * @param scale        精确范围(小数点后几位)
     * @param
     */
    public static String add(String value1, String value2, int scale, int mode) {
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        BigDecimal result = b1.add(b2);
        // mode为0，则不需要精确
        if (mode != 0) {
            result = result.setScale(scale, mode);
        }
        return result.toString();
    }

    public static int compareTo(String value1, String value2, int scale, int mode) {
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        BigDecimal result = b1.subtract(b2);
        // mode为0，则不需要精确
        if (mode != 0) {
            result = result.setScale(scale, mode);
        }
        return result.compareTo(BigDecimal.ZERO);
    }

    /**
     * 提供精确的除法运算方法divide
     *
     * @param value1 被除数
     * @param value2 除数
     */
    public static String divide(String value1, String value2) {
        try {
            return divide(value1, value2, 0, null);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 提供精确的百分比运算方法 (默認四捨五入) 返回除法百分比
     *
     * @param value1 被除数
     * @param value2 除数
     * @param scale  精确范围(小数点后几位)
     */
    public static String percentage(String value1, String value2, int scale) {
        NumberFormat numberFormat = NumberFormat.getPercentInstance();
        numberFormat.setMaximumFractionDigits(scale); //精确到位。

        try {
            String divide = divide(value1, value2, 10, RoundingMode.HALF_UP);

            String format = numberFormat.format(Float.parseFloat(divide));

            return format;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 提供精确加法计算的百分比  加法方法
     */
    public static String addPercentage(String value1, String value2, int scale) {
        NumberFormat numberFormat = NumberFormat.getPercentInstance();
        numberFormat.setMaximumFractionDigits(scale); //精确到位。

        try {
            double v1 = numberFormat.parse(value1).doubleValue();
            double v2 = numberFormat.parse(value2).doubleValue();

            String add = add(Double.toString(v1), Double.toString(v2));

            String format = numberFormat.format(Float.parseFloat(add));

            return format;

        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 提供精确加法计算的百分比  加法方法
     */
    public static String subtractPercentage(String value1, String value2, int scale, int isPercentage) {
        NumberFormat numberFormat = NumberFormat.getPercentInstance();
        numberFormat.setMaximumFractionDigits(scale); //精确到位。

        try {
            double v1 = numberFormat.parse(value1).doubleValue();
            double v2 = numberFormat.parse(value2).doubleValue();
            String subtract = subtract(Double.toString(v1), Double.toString(v2));

            if (1 == isPercentage) {
                return numberFormat.format(Float.parseFloat(subtract));
            }

            return subtract;

        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 提供精确的百分比运算方法 (默認四捨五入) 比较大小
     *
     * @param value1 大百分比
     * @param value2 比较百分比
     * @param scale  精确范围(小数点后几位)
     */
    public static Boolean comparisonPercentage(String value1, String value2, int scale) {

        Boolean isLimit = Boolean.FALSE;
        try {
            NumberFormat numberFormat = NumberFormat.getPercentInstance();
            numberFormat.setMaximumFractionDigits(scale); //精确到位。
            double v1 = numberFormat.parse(value1).doubleValue();
            double v2 = numberFormat.parse(value2).doubleValue();

            BigDecimal data1 = new BigDecimal(Double.toString(v1));
            BigDecimal data2 = new BigDecimal(Double.toString(v2));

            if (data1.compareTo(data2) > 0) {
                isLimit = Boolean.TRUE;
            }

            return isLimit;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return isLimit;
    }

    /**
     * 提供精确的百分比运算方法 (默認四捨五入) 比较大小
     *
     * @param value1 被除数
     * @param value2 除数
     * @param scale  精确范围(小数点后几位)
     */
    public static Boolean comparison(String value1, String value2) {
        Boolean isLimit = Boolean.FALSE;

        BigDecimal data1 = new BigDecimal(value1);
        BigDecimal data2 = new BigDecimal(value2);

        if (data1.compareTo(data2) >= 0) {
            isLimit = Boolean.TRUE;
        }

        return isLimit;
    }

    /**
     * (默認四捨五入) 取整
     */
    public static String roundingInt(String value1) {

        BigDecimal bigDecimal = new BigDecimal(value1).setScale(0, BigDecimal.ROUND_HALF_UP);

        return bigDecimal.toString();
    }

    public static String convertPercentage(String value1) {

        NumberFormat numberFormat = NumberFormat.getPercentInstance();
        numberFormat.setMaximumFractionDigits(2); //精确到位。
        double v1 = 0;
        try {
            v1 = numberFormat.parse(value1).doubleValue();
            String format = numberFormat.format(v1);

            return format;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return "";
    }



    public static void main(String[] args) throws ParseException {
        //分母
        Date current = TimeUtils.currentTime();
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(new Date());
        calendar.add(calendar.DATE, -1);

        //昨天
        Date yesterday = calendar.getTime();
        calendar.setTime(new Date());
        calendar.add(calendar.DATE, -2);

        //前天
        Date beforeYesterday = calendar.getTime();

        System.out.println(TimeUtils.parseDate(current, "yyyy-MM-dd HH:mm:ss"));
        System.out.println(TimeUtils.parseDate(yesterday, "yyyy-MM-dd HH:mm:ss"));
        System.out.println(TimeUtils.parseDate(beforeYesterday, "yyyy-MM-dd HH:mm:ss"));

    }

    /**
     * 提供精确的除法运算方法divide(默認四捨五入)
     *
     * @param value1 被除数
     * @param value2 除数
     * @param scale  精确范围(小数点后几位)
     */
    public static String divide(String value1, String value2, int scale) {

        try {
            return divide(value1, value2, scale, RoundingMode.HALF_UP);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 提供精确的除法运算方法divide
     *
     * @param value1       被除数
     * @param value2       除数
     * @param scale        精确范围(小数点后几位)
     * @param roundingMode 精確模式
     */
    public static String divide(String value1, String value2, int scale, RoundingMode roundingMode)
            throws IllegalAccessException {
        // 如果精确范围小于0，抛出异常信息
        if (scale < 0) {
            throw new IllegalAccessException("精确度不能小于0");
        }
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        // roundingMode为null，则不需要精确
        if (roundingMode != null) {
            return new Double(b1.divide(b2, scale, roundingMode).doubleValue()).toString();
        } else {
            return new Double(b1.divide(b2).doubleValue()).toString();
        }
    }

    /**
     * 比较大小 ：返回较大的那个
     */
    public static String getMax(String value1, String value2) {
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return new Double(b1.max(b2).doubleValue()).toString();
    }

    /**
     * 比较大小 ：返回较小的那个
     */
    public static String getMin(String value1, String value2) {
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return new Double(b1.min(b2).doubleValue()).toString();
    }


    /**
     * 提供精确乘法运算的multiply方法
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @return 两个参数的积
     */
    public static String multiply(String value1, String value2) {
        return multiply(value1, value2, 0, 0);
    }

    /**
     * 提供精确乘法运算的multiply方法(默認四捨五入)
     *
     * @param value1 被乘数
     * @param value2 乘数
     * @param scale  精确范围(小数点后几位)
     */
    public static String multiply(String value1, String value2, int scale) {
        return multiply(value1, value2, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 提供精确乘法运算的multiply方法
     *
     * @param value1       被乘数
     * @param value2       乘数
     * @param scale        精确范围(小数点后几位)
     * @param roundingMode 精確模式
     */
    public static String multiply(String value1, String value2, int scale, int mode) {
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        BigDecimal result = b1.multiply(b2);
        // mode为0，则不需要精确
        if (mode != 0) {
            result = result.setScale(scale, mode);
        }
        return result.toString();
    }

    /**
     * 提供精确减法运算的subtract方法
     *
     * @param value1 被减数
     * @param value2 减数
     * @return 两个参数的差
     */
    public static String subtract(String value1, String value2) {
        return subtract(value1, value2, 0, 0);
    }

    /**
     * 提供精确减法运算的subtract方法(默認四捨五入)
     *
     * @param value1 被减数
     * @param value2 减数
     * @param scale  精确范围(小数点后几位)
     */
    public static String subtract(String value1, String value2, int scale) {
        return subtract(value1, value2, scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 提供精确减法运算的subtract方法
     *
     * @param value1       被减数
     * @param value2       减数
     * @param scale        精确范围(小数点后几位)
     * @param roundingMode 精確模式
     */
    public static String subtract(String value1, String value2, int scale, int mode) {
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        BigDecimal result = b1.subtract(b2);
        // mode为0，则不需要精确
        if (mode != 0) {
            result = result.setScale(scale, mode);
        }
        return result.toString();
    }
}
